<?php

namespace app\models;

use app\components\BaseActiveRecord;
use app\helpers\UserHelper;
use Yii;
use yii\base\Exception;
use yii\helpers\ArrayHelper;
use yii\helpers\Console;
use yii\helpers\FileHelper;

/**
 * This is the model class for table "{{%user}}".
 *
 * @property int $id
 * @property string $phone
 * @property string $device_type
 * @property string $user_priority
 * @property string $pwd_id
 * @property string $esn
 * @property string $imsi
 * @property string $vo_coder
 * @property string $amf
 * @property string $sqn
 * @property string $k
 * @property string $op
 * @property string $opc
 * @property string $start
 * @property string $stop
 * @property int $create_time
 * @property int $is_group
 * @property int $is_sms
 * @property int $is_call_waiting
 * @property int $is_more_call
 * @property int $is_call_out
 * @property int $is_call_in
 * @property int $is_call_group
 * @property int $is_fwd_no_answer
 * @property int $is_fwd_on_busy_num
 * @property int $is_fwd_unc
 * @property int $is_fwd_na_num
 * @property int $is_full_duplex
 * @property int $is_half_duplex
 * @property int $yb
 * @property int $yy
 * @property int $gps
 * @property int $is_secrecy
 * @property string $fwd_phone
 */
class User extends BaseActiveRecord {
    /**
     * {@inheritdoc}
     */
    public static function tableName() {
        return '{{%user}}';
    }

    /**
     * {@inheritdoc}
     */
    public function rules() {
        return [
            [['phone', 'device_type', 'vo_coder', 'amf', 'user_priority', 'start', 'stop', 'esn', 'imsi', 'sqn', 'k', 'op', 'opc'], 'required'],

            [['create_time', 'is_group', 'is_sms', 'is_call_waiting', 'is_more_call', 'is_call_out', 'is_call_in', 'is_call_group', 'is_fwd_no_answer', 'is_fwd_on_busy_num', 'is_fwd_unc', 'is_fwd_na_num', 'is_full_duplex', 'is_half_duplex', 'is_secrecy', 'yb', 'yy', 'gps'], 'integer'],
            [['phone', 'device_type', 'vo_coder', 'amf'], 'string', 'max' => 20],
            [['user_priority', 'start', 'stop'], 'string', 'max' => 10],
            [['pwd_id', 'imsi', 'esn', 'fwd_phone'], 'string', 'max' => 100],
            [['sqn'], 'string', 'max' => 30],
            [['imsi'], 'unique'],
            [['k', 'op', 'opc'], 'string', 'max' => 60],
        ];
    }

    /**
     * {@inheritdoc}
     */
    public function attributeLabels() {
        return [
            'id' => 'ID',
            'phone' => '电话号码',
            'device_type' => '设备类型',
            'user_priority' => '用户优先级',
            'pwd_id' => '密码模块ID',
            'imsi' => '用户识别码',
            'vo_coder' => '语音编码',
            'amf' => 'AMF',
            'sqn' => 'SQN',
            'esn' => 'ESN',
            'k' => 'K',
            'op' => 'OP',
            'opc' => 'OPC',
            'start' => 'Start',
            'stop' => 'Stop',
            'create_time' => 'Create Time',
            'is_group' => '数据业务',
            'is_sms' => '短信业务',
            'is_call_waiting' => '呼叫等待',
            'is_more_call' => '三方通话',

            'is_call_out' => '呼出限制',
            'is_call_in' => '呼入限制',
            'is_call_group' => '组呼业务',
            'is_fwd_no_answer' => '无应答前转',
            'is_fwd_on_busy_num' => '遇忙前转',
            'is_fwd_unc' => '无条件前转',
            'is_fwd_na_num' => '不可达前转',
            'is_full_duplex' => '全双工',
            'is_half_duplex' => '半双工',
            'is_secrecy' => '保密业务',
            'fwd_phone' => '前转号码'
        ];
    }

    public function beforeValidate() {
        if (strtotime($this->stop) <= strtotime($this->start)) {
            $this->addError('stop', '结束时间不能小于开始时间');
            return false;
        }
        return parent::beforeValidate();
    }

    public function afterSave($insert, $changedAttributes) {
        parent::afterSave($insert, $changedAttributes);
        if ($this->isGenerateFile) {
            self::generateFiles($this, $insert);
        }
    }

    public function getViewName($field) {
        $v = intval($this->getAttribute($field));
        $map = [self::YES => '<i class="glyphicon glyphicon-ok"></i>', self::NO => '<i class="glyphicon glyphicon-remove"></i>'];
        return ArrayHelper::getValue($map, $v, NULL);
    }

    public static function generateFiles(User $user, $insert) {
        $profile = $user->getProfile();
        $profileExt = $user->getProfileExt();
        $fwd = $user->getFwd();

        $template = "UE:{$user->imsi}|{$user->phone}|{$user->pwd_id}|{$user->device_type}|END\n";
        $template .= "AuC_Data:{$user->k} |{$user->op} |{$user->opc} |{$user->amf} ||{$user->sqn} |{$user->start}|{$user->stop}|END\n";
        $template .= "CS_Data:{$user->esn}||||||0||{$user->vo_coder}|{$profile}|{$profileExt}|{$fwd}|||END\n";

        if ($user->is_group) {
            $template .= "PS_Data:{$user->esn}||||||0||{$user->vo_coder}|{$profile}|{$profileExt}|||||END\n";
        }

        $groups = GroupUser::find()->where(['phone' => $user->phone])->groupBy('group_num')->asArray()->all();
        foreach ($groups as $group) {
            $template .= "GROUP_Data:{$group['group_num']}||||END\n";
        }
        try {
            FileHelper::createDirectory(FILE_ROOT);
        } catch (Exception $e) {
        }
        $imsiFile = FILE_ROOT . "/{$user->imsi}.info";
        @file_put_contents($imsiFile, $template);

        if ($insert) {
            $phoneFile = FILE_ROOT . "/{$user->phone}.info";
            exec("ln -s {$imsiFile} {$phoneFile}");
        }
    }

    /**
     * @param $file
     * @throws \yii\db\Exception
     */
    public static function parseFile($file) {
        $string = file_get_contents($file);
        if (empty($string) || strpos($string, 'UE') === FALSE) {
            Console::stdout("{$file} 解析失败.\n");
            return;
        }
        self::parseString($string);
    }

    /**
     * @param $string
     * @throws \yii\db\Exception
     */
    public static function parseString($string) {
        if (strpos($string, 'UE') === FALSE) {
            return;
        }
        $model = NULL;
        $lines = explode("\n", $string);
        $line = str_replace('UE:', '', $lines[0]);
        $data = explode('|', $line);
        $phone = $data[1];
        $model = User::findOne(['phone' => $phone]);

        if (!$model) {
            $model = new User();
        }
        $model->isGenerateFile = false;

        foreach ($lines as $line) {
            $model->parseUE($line);
            $model->parseAUC($line);
            $model->parseCS($line);
        }
//        print_r($model->attributes);
        $model->save(FALSE);
    }

    protected function parseUE($line) {
        if (strpos($line, 'UE') === FALSE) {
            return;
        }
        $line = str_replace('UE:', '', $line);
        $data = explode('|', $line);
        $this->imsi = $data[0];
        $this->phone = $data[1];
        $this->pwd_id = $data[2];
        $this->device_type = $data[3];
    }

    protected function parseAUC($line) {
        if (strpos($line, 'AuC_Data') === FALSE) {
            return;
        }
        $line = str_replace('AuC_Data:', '', $line);
        $data = explode('|', $line);
        $this->k = $data[0];
        $this->op = $data[1];
        $this->opc = $data[2];
        $this->amf = $data[3];
        $this->sqn = $data[5];
        $this->start = $data[6];
        $this->stop = $data[7];
    }

    protected function parseCS($line) {
        if (strpos($line, 'CS_Data') === FALSE) {
            return;
        }
        $line = str_replace('CS_Data:', '', $line);
        $data = explode('|', $line);
        $this->esn = $data[0];
        $this->vo_coder = $data[8];
        $profile = $data[9];
        $profileExt = $data[10];

        if ($profile) {
            foreach (UserHelper::$profileMap as $k => $v) {
                $val = ($profile & $v) == $v ? 1 : 0;
                $this->setAttribute($k, $val);
            }
            $this->user_priority = ($profile & 0xF0000000) >> 28;
        }
        if ($profileExt) {
            foreach (UserHelper::$profileExt as $k => $v) {
                $this->setAttribute($k, ($profile & $v) == $v ? 1 : 0);
            }
        }
    }

    protected function getFwd() {
        $html = $this->is_fwd_unc ? $this->fwd_phone : '';
        $html .= '|' . ($this->is_fwd_on_busy_num ? $this->fwd_phone : '');
        $html .= '|' . ($this->is_fwd_no_answer ? $this->fwd_phone : '');
        $html .= '|' . ($this->is_fwd_na_num ? $this->fwd_phone : '');
        return $html;
    }

    protected function getProfileExt() {
        $map = UserHelper::$profileExt;
        $ext = 0;
        foreach ($map as $k => $v) {
            if ($this[$k]) {
                $ext += $v;
            }
        }
        return $ext;
    }

    public function getProfile() {
        $map = UserHelper::$profileMap;
        $profile = 0;
        foreach ($map as $k => $v) {
            if ($this[$k]) {
                $profile += $v;
            }
        }
        foreach (UserHelper::$userPriorityMap as $k => $v) {
            if (intval($k) === intval($this->user_priority)) {
                $profile += $v;
                break;
            }
        }
        return $profile;
    }
}
